<?php

class AImageUpload
{
	/**
	 * @var int - максимально допустимый размер файла в байтах
	 */
	private $_maxFileSize = 3145728;

	/**
	 * @var array - масив разрешенных расширений для файлов, которые будут загружены
	 */
	private $_allowExtensions = array('jpg','png','gif');

	/**
	 * @var array - масив разрешенных типов файлов, которые будут загружены
	 */
	private $_allowMimeType = array('image/jpeg','image/gif','image/png');

	/**
	 * @var string директория в папке getImagesFolder() в которую будут загружатся файлы
	 */
	private $_uploadFolderName;

	/**
	 * @var int - идентификатор групы изображений
	 */
	private $_imageGroupId;

	/**
	 * @var CUploadedFile - файл который будет загружен на сервер
	 */
	private $_file;

	/**
	 * @var string - альтернативный текст для изображения, передаеться пользователем через $_POST
	 */
	private $_alt;

	public function upload()
	{
		$result = $this->getFile();
		if($result!==true){
			return AHelper::jsonEncode(array('errors'=>$result));
		}
		$imageSize = getimagesize($this->_file->getTempName());
		$transaction = Yii::app()->db->beginTransaction();
		try{
			$image = new Image();
			if($this->_imageGroupId==0){
				$this->createGroup();
			}
			$image->group_id = $this->_imageGroupId;
			$image->name = $this->_file->getName();
			$image->alt = $this->_alt;
			if(!$image->save()){
				$errors = array_map(function($item){
					return implode(',,', $item);
				}, $image->getErrors());
				throw new Exception(implode(',,',$errors));
			}
			if(!$this->saveFile()){
				throw new Exception($this->_file->getError());
			}
			$transaction->commit();
		}catch(Exception $e){
			$transaction->rollback();
			return AHelper::jsonEncode(array('errors'=>explode(',,',$e->getMessage())));
		}
		return AHelper::jsonEncode(array(
			'result'=>true,
			'imageGroupId'=>$this->_imageGroupId,
			'imageId'=>$image->id,
			'itemImage'=>$image->item_image,
			'fileName'=>$this->_file->getName(),
			'alt'=>$this->_alt,
			'fileSize'=>$this->_file->getSize(),
			'imageWidth'=>$imageSize[0],
			'imageHeight'=>$imageSize[1],
			'uploadFolderName'=>$this->_uploadFolderName,
			'imageFolder'=>$this->getImagesFolder(),
			'priority'=>0,
		));
	}

	private function createGroup()
	{
		$imageFolder = new ImageFolder();
		$folder = $imageFolder->find('folder_name=:folderName' , array(':folderName' => $this->_uploadFolderName));
		if ($folder === null) {
			$folder = new ImageFolder();
			$folder->folder_name = $this->_uploadFolderName;
			$folder->save();
		}
		$imageGroup = new ImageGroup();
		$imageGroup->folder_id = $folder->id;
		$imageGroup->save();
		$this->_imageGroupId = $imageGroup->id;
	}

	public function deleteImage($id)
	{
		$image = new Image();
		try{
			$image = $image->findAllByPk($id);
			if(count($image)==0){
				throw new Exception(Yii::t('imageInput','Unknown file id'));
			}
			$image = $image[0];
			$path = Yii::app()->basePath . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . $this->getImagesFolder() .
				DIRECTORY_SEPARATOR . $image->group->folder->folder_name . DIRECTORY_SEPARATOR .
				$image->group_id . DIRECTORY_SEPARATOR . $image->name;
			if(file_exists($path)){
				unlink($path);
			}
			$image->delete();
			return AHelper::jsonEncode(array('result'=>true));
		}catch(Exception $e){
			return AHelper::jsonEncode(array('error'=>$e->getMessage()));
		}
	}

	/**
	 * Сохраняет файл на диске, проверяет наличие папок на диске в случае их отсутствия создает их
	 * Возвращает результат работы CUploadedFile::saveAs()
	 * @return bool
	 */
	private function saveFile(){
		$uploadFolder = Yii::app()->basePath.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$this->getImagesFolder();
		if(!file_exists($uploadFolder)){
			mkdir($uploadFolder,0777);
		}
		$uploadFolder .= DIRECTORY_SEPARATOR.$this->_uploadFolderName;
		if(!file_exists($uploadFolder)){
			mkdir($uploadFolder,0777);
		}
		$uploadFolder .= DIRECTORY_SEPARATOR.$this->_imageGroupId;
		if(!file_exists($uploadFolder)){
			mkdir($uploadFolder,0777);
		}
		return $this->_file->saveAs($uploadFolder.DIRECTORY_SEPARATOR.$this->_file->getName());
	}

	/**
	 * Проверяет входные данные на прпвильность возвращат масив ошибок, в случае неудачи. или true в случае успеха
	 * @return array | bool
	 */
	private function getFile(){
		$error = array();
		if(!isset($_POST['imageId'])){
			$error[] = Yii::t('imageInput','Unknown file id');
		}else{
			$this->_imageGroupId = (int)$_POST['imageId'];
		}
		if(!isset($_POST['folderName']) || empty($_POST['folderName'])){;
			$error[] = Yii::t('imageInput','Not specified folder to save the file');
		}else{
			$this->_uploadFolderName = $_POST['folderName'];
		}
		if(!isset($_POST['alt']) || empty($_POST['alt'])){;
			$error[] = Yii::t('imageInput','Alternative text is not specified');
		}else{
			$this->_alt = $_POST['alt'];
		}
		$this->_file = CUploadedFile::getInstanceByName('file');
		if($this->_file===null){
			$error[] = Yii::t('imageInput','The file was not transferred');
			return $error;
		}
		if($this->_file->getSize()>$this->_maxFileSize){
			$error[] = Yii::t(
				'imageInput',
				'File too large, the maximum size - {maxFileSize}Mb.',
				array('{maxFileSize}'=>$this->_maxFileSize/1024/1024)
			);
		}
		if(array_search($this->_file->getExtensionName(),$this->_allowExtensions)===false){
			$error[] = Yii::t(
				'imageInput',
				'Invalid extension "{extension}", use the {allowExtensions}',
				array(
					'{extension}'=>$this->_file->getExtensionName(),
					'{allowExtensions}'=>implode(', ', $this->_allowExtensions)
				)
			);
		}
		$mimeType = CFileHelper::getMimeType($this->_file->getTempName());
		if(array_search($mimeType,$this->_allowMimeType)===false){
			$error[] = Yii::t(
				'imageInput',
				'Invalid mime type "{mimeType}", use the {allowMimeType}',
				array('{mimeType}'=>$mimeType,'{allowMimeType}'=>implode(', ',$this->_allowMimeType))
			);
		}
		return count($error)==0 ? true : $error;
	}

	/**
	 * @static
	 * @return string - основная папка с файлами
	 */
	public static function getImagesFolder(){
		return 'userfiles';
	}
}
